/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package czStvDpds.movement;

import czStvDpds.centrallogic.Direction;
import czStvDpds.centrallogic.PlayerMovement;
import czStvDpds.graphics3D.GraphicalPlayer;
import czStvDpds.graphics3D.geometry.Object3D;
import czStvDpds.input.LWJGLKeyEvent;
import czStvDpds.input.LWJGLMouseEvent;

/**
 * Edited by Divad
 *
 * @author Vašek
 */
public class Player implements AbstractPlayer, GraphicalPlayer {

    static final double speed = 8.0 / 40.0 / 40.0; //Konstanta rychlosti postavy (3 policka/sec)
    //Pozn. (Vašek): Vydělil jsem ještě jednou 40, standardním časem refreshe, abych vyrovnal změny
//    static final double mouseSpeed = 0.3;
    static final double mouseSpeed = 2;
    double x, y;
    double yaw, pitch;
    boolean forward = false, back = false;
    boolean left = false, right = false;
    String name = "defaultname";

    public Player(double x, double y, double yaw) { //Center - střed obrazovky, kde bude myš
        this.x = x;
        this.y = y;
        this.yaw = yaw;
        pitch = 0; //0 = rovně, 90 = nahoru a -90 = dolů? Záleží na grafice
    }

    public Player(double x, double y, double yaw, String name) { //Center - střed obrazovky, kde bude myš
        this.x = x;
        this.y = y;
        this.yaw = yaw;
        this.name = name;
        pitch = 0; //0 = rovně, 90 = nahoru a -90 = dolů? Záleží na grafice
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public double getPitch() {
        return pitch;
    }

    @Override
    public double getX() {
        return x;
    }

    @Override
    public double getY() {
        return y;
    }

    @Override
    public double getYaw() {
        return yaw;
    }

    @Override
    public void setX(double x) {
        this.x = x;
    }

    @Override
    public void setY(double y) {
        this.y = y;
    }

    @Override
    public void setYaw(double yaw) {
        this.yaw = yaw;
    }

    @Override
    public void setPitch(double pitch) {
        this.pitch = pitch;
    }

    @Override
    public void movePlayer(PlayerMovement m, int time) {
        // Změna yaw
        if (m.isRelative()) {
            this.yaw -= m.getYaw();
        } else {
            this.yaw = m.getYaw();
        }

        // Změna X a Y
        if (m.getDir() != null) {
            this.yaw = this.yaw % 360;
            double newX = this.x;
            double newY = this.y;
            if (m.getDir() == Direction.FORWARD) {
                newX += Math.cos(Math.toRadians(yaw)) * speed * time;
                newY += Math.sin(Math.toRadians(yaw)) * (-speed) * time;
            } else if (m.getDir() == Direction.BACK) {
                newX -= Math.cos(Math.toRadians(yaw)) * speed * time;
                newY -= Math.sin(Math.toRadians(yaw)) * (-speed) * time;
            } else if (m.getDir() == Direction.LEFT) {
                newX += Math.cos(Math.toRadians(yaw + 90)) * speed * time;
                newY += Math.sin(Math.toRadians(yaw + 90)) * (-speed) * time;
            } else if (m.getDir() == Direction.RIGHT) {
                newX += Math.cos(Math.toRadians(yaw - 90)) * speed * time;
                newY += Math.sin(Math.toRadians(yaw - 90)) * (-speed) * time;
            }

            // X
//            if (!CollisionManager.getCollisionManager().isShapeCollision(newX, y)) {
            if (!CollisionManager.getCollisionManager().isBetterShapeCollision(newX, this.y)) {
                this.x = newX;
            }

            // Y
//            if (!CollisionManager.getCollisionManager().isShapeCollision(x, newY)) { // Zatim neresi zarovnani hrace se zdi
            if (!CollisionManager.getCollisionManager().isBetterShapeCollision(this.x, newY)) {
                this.y = newY;
            }
        } else if (m.isRelative()) {
            this.x += m.getX();
            this.y += m.getY();
        } else {
            this.x = m.getX();
            this.y = m.getY();
        }
    }

    /**
     * @author Divad
     *
     * @param e
     */
    @Override
    public void keyAction(LWJGLKeyEvent e) {
        if (e.getState()) {
            switch (e.getKey()) {
                case LWJGLKeyEvent.KEY_W:
                    forward = true;
                    back = false;
                    break;
                case LWJGLKeyEvent.KEY_S:
                    back = true;
                    forward = false;
                    break;
                case LWJGLKeyEvent.KEY_A:
                    left = true;
                    right = false;
                    break;
                case LWJGLKeyEvent.KEY_D:
                    right = true;
                    left = false;
                    break;
                /*
                 * case KeyEvent.VK_Q: //Testování yaw += 30; break;
                 */
            }
        } else {
            switch (e.getKey()) {
                case LWJGLKeyEvent.KEY_W:
                    forward = false;
                    break;
                case LWJGLKeyEvent.KEY_S:
                    back = false;
                    break;
                case LWJGLKeyEvent.KEY_A:
                    left = false;
                    break;
                case LWJGLKeyEvent.KEY_D:
                    right = false;
                    break;
                /*
                 * case KeyEvent.VK_Q: //Testování yaw += 30; break;
                 */
            }
        }
    }

    /**
     * @author Divad
     *
     * @param e
     */
    @Override
    public void mouseAction(LWJGLMouseEvent e) {
        if (e.getdX() != 0) {
            this.yaw += e.getdX() * -1 * mouseSpeed;
        }
        if (e.getdY() != 0) {
            this.pitch -= e.getdX() * mouseSpeed;
        }
    }

    @Override
    public void step() {
        // @author Vašek
        /*
         * yaw = yaw % 360; if (forward) { if (!back) { x = x +
         * Math.sin(Math.toRadians(yaw)) * speed; y = y +
         * Math.cos(Math.toRadians(yaw)) * speed; } } else if (back) { x = x -
         * Math.sin(Math.toRadians(yaw)) * speed; y = y -
         * Math.cos(Math.toRadians(yaw)) * speed; } if (left) { if (!right) { x
         * = x + Math.sin(Math.toRadians(yaw + 90)) * speed; y = y +
         * Math.cos(Math.toRadians(yaw + 90)) * speed; } } else if (right) { x =
         * x + Math.sin(Math.toRadians(yaw - 90)) * speed; y = y +
         * Math.cos(Math.toRadians(yaw - 90)) * speed; }
         */

        yaw = yaw % 360;
        if (forward) {
            x += Math.cos(Math.toRadians(yaw)) * speed;
            y += Math.sin(Math.toRadians(yaw)) * (-speed);
        }
        if (back) {
            x -= Math.cos(Math.toRadians(yaw)) * speed;
            y -= Math.sin(Math.toRadians(yaw)) * (-speed);
        }
        if (left) {
            x += Math.cos(Math.toRadians(yaw + 90)) * speed;
            y += Math.sin(Math.toRadians(yaw + 90)) * (-speed);
        }
        if (right) {
            x += Math.cos(Math.toRadians(yaw - 90)) * speed;
            y += Math.sin(Math.toRadians(yaw - 90)) * (-speed);
        }
    }
    /////////////////////////grafická šást/////////////////////////////////////
    private Object3D mesh;

    @Override
    public Object3D getObject3D() {
        return this.mesh;
    }

    @Override
    public void setObject3D(Object3D mesh) {
        this.mesh = mesh;
    }

    @Override
    public double getGraphicsX() {
        return this.getX();
    }

    @Override
    public double getGraphicsY() {
        return this.getY();
    }

    @Override
    public double getGraphicsYaw() {
        return this.getYaw();
    }
}
